package com.clickpaas.governmentcloud.service.policymatchextservice.impl;

import com.alibaba.fastjson.JSONObject;
import com.bizcloud.ipaas.tb4093760b8224c4fbcff37d3fa266753.d20210207141638.codegen.TmatchingresultsApi;
import com.bizcloud.ipaas.tb4093760b8224c4fbcff37d3fa266753.d20210207141638.model.*;
import com.clickpaas.governmentcloud.common.ConstantExt;
import com.clickpaas.governmentcloud.common.ServerResponse;
import com.clickpaas.governmentcloud.common.TokenCommon;
import com.clickpaas.governmentcloud.entity.policyEntity.PolicyEntity;
import com.clickpaas.governmentcloud.service.exactmatchingservice.ExactMatchingService;
import com.clickpaas.governmentcloud.service.policymatchextservice.MatchExtMainService;
import com.clickpaas.governmentcloud.service.policymatchextservice.MatchExtService;
import com.clickpaas.governmentcloud.utils.policycondcalutils.PolicyCondCal;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.*;

/**
 * @company <上海爱湃斯科技有限公司>
 * @email <zhihui.peng@clickpaas.com>
 * @author huiye
 * @decription: 政策匹配处理方法
 * @date 2020/12/21 4:17 下午
 */
@Slf4j
@Service
public class MatchExtMainServiceImpl implements MatchExtMainService {

    @Resource
    ExactMatchingService exactMatchingService;
    @Resource
    TmatchingresultsApi tmatchingresultsApi;
    /**
     *匹配工具
     */
    @Resource
    private PolicyCondCal policyCondCal;
    /**
     *上海市科技小巨人企业认定
     */
    @Resource
    LittleTechGiantServiceImpl littleTechGiantService;

    /**
     * 上海市级企业技术中心认定
     */
    @Resource
    EnterpriseTechCenterServiceImpl techCenterService;

    /**
     * 国家科技型中小企业评价
     */
    @Resource
    NatTechSMEEvaServiceImpl natTechSMEEvaService;

    /**
     * 中小企业发展专项资金（中小企业升级）
     */
    @Resource
    SpecialSMECompUpgradeServiceImpl specialSMECompUpgradeService;

    /**
     * 中小企业发展专项资金（中小企业创新）
     */
    @Resource
    SpefundSMEDevelopServiceImpl spefundSMEDevelopService;

    /**
     * 科技型中小企业创新资金项目
     */
    @Resource
    TechSMEFundProServiceImpl techSMEFundProService;

    /**
     * 上海市高新技术企业认定
     */
    @Resource
    HightechCopCertifServiceImpl hightechCopCertifService;

    /**
     * 上海市高新技术企业入库培育
     */
    @Resource
    HighTechWarehousServiceImpl highTechWarehousService;

    /**
     * 上海市专精特新中小企业认定
     */
    @Resource
    SpeciaAndNewServiceImpl speciaAndNewService;

    /**
     * 多线程执行精确匹配政策
     *
     * @param policy 匹配数据实体类
     * @return ServerResponse
     */
    @Override
    public ServerResponse<?> exactMultiThreadExecutMatchPolicy(PolicyEntity policy,String matchiScheme) {
        //新增匹配类别
        if (StringUtils.isNotBlank(matchiScheme)){
            policy.setType(ConstantExt.QUICK_MATCH);
        }else {
            policy.setType(ConstantExt.EXACT_MATCH);
        }
        //ExecutorService executorService = Executors.newCachedThreadPool();
        ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
        List<Callable<ServerResponse<?>>> tasks = Lists.newArrayList();
        //加入任务
        tasks.add(getCallable(littleTechGiantService,policy));
        tasks.add(getCallable(techCenterService,policy));
        tasks.add(getCallable(natTechSMEEvaService,policy));
        tasks.add(getCallable(specialSMECompUpgradeService,policy));
        tasks.add(getCallable(spefundSMEDevelopService,policy));
        tasks.add(getCallable(techSMEFundProService,policy));
        tasks.add(getCallable(hightechCopCertifService,policy));
        tasks.add(getCallable(highTechWarehousService,policy));
        tasks.add(getCallable(speciaAndNewService,policy));

        List<ServerResponse<?>> returnCodeList = Collections.synchronizedList(new ArrayList<>());

        try {
            List<Future<ServerResponse<?>>> futureList = executorService.invokeAll(tasks, 3000, TimeUnit.MILLISECONDS);
            for (Future<ServerResponse<?>> future : futureList) {
                // 获取线程执行结果
                try {
                    ServerResponse<?> serverResponse = future.get();
                    if (null == serverResponse)continue;
                    returnCodeList.add(serverResponse);
                } catch (ExecutionException e) {
                    log.info("匹配政策执行线程：【{}】",e);
                }
            }
        } catch (InterruptedException e) {
            log.info("匹配政策执行线程：【{}】",e);
        }finally {
            //关闭线程
            executorService.shutdown();
        }

        //处理执行结果
        if(returnCodeList.size() >0){
            for(ServerResponse<?> serverResponse : returnCodeList){
                if (serverResponse.getcode()==ConstantExt._SUCCESS_CODE){
                    return ServerResponse.createSuccess(ConstantExt._SUCCESS_MESSAGE);
                }
            }
        }
        return ServerResponse.createError(ConstantExt._ERROR_MESSAGE);
    }

    /**
     * 正常顺序精确匹配政策
     *
     * @param policy 匹配数据实体类
     * @return ServerResponse
     */
    @Override
    public ServerResponse<?> exactNormalOrderMatchPolicy(PolicyEntity policy,String matchiScheme) {
        ArrayList<ServerResponse<?>> returnResponse = new ArrayList<>();
        //新增匹配类别
        if (StringUtils.isNotBlank(matchiScheme)){
            policy.setType(ConstantExt.QUICK_MATCH);
        }else {
            policy.setType(ConstantExt.EXACT_MATCH);
        }
        returnResponse.add(littleTechGiantService.isMatchSuccess(policy));
        returnResponse.add(techCenterService.isMatchSuccess(policy));
        returnResponse.add(natTechSMEEvaService.isMatchSuccess(policy));
        returnResponse.add(specialSMECompUpgradeService.isMatchSuccess(policy));
        returnResponse.add(spefundSMEDevelopService.isMatchSuccess(policy));
        returnResponse.add(techSMEFundProService.isMatchSuccess(policy));
        returnResponse.add(hightechCopCertifService.isMatchSuccess(policy));
        returnResponse.add(highTechWarehousService.isMatchSuccess(policy));
        returnResponse.add(speciaAndNewService.isMatchSuccess(policy));

        if(returnResponse.size() >0){
            for(ServerResponse<?> serverResponse : returnResponse){
                if (serverResponse.getcode()==ConstantExt._SUCCESS_CODE){
                    return ServerResponse.createSuccess(ConstantExt._SUCCESS_MESSAGE);
                }
            }
        }
        return ServerResponse.createError(ConstantExt._ERROR_MESSAGE);
    }

    /**
     * 多线程执行快速匹配政策
     *
     * @param token 查询token
     * @return ServerResponse
     */
    @Override
    public ServerResponse<?> fastMutiThreadExecutMatchPolicy(String token) {
        ServerResponse<?> serverResponse = ServerResponse.createError(ConstantExt._ERROR_MESSAGE);
        PolicyEntity policyEntity = getEntityFromToken(token);
        if (null != policyEntity){
            policyEntity.setTypeofDataSource(ConstantExt.USER_PROCESSING);
            return fastMExecutMatchPolicy(policyEntity);
        }
        return serverResponse;
    }

    public ServerResponse<?> fastMExecutMatchPolicy(PolicyEntity policyEntity){
        //政策匹配前数据处理
        dealOldData(policyEntity);
        //调用多线程精确匹配方法
        String matchiScheme = ConstantExt._FAST_MARK;
        return exactMultiThreadExecutMatchPolicy(policyEntity,matchiScheme);
    }

    /**
     * 正常顺序快速匹配政策
     *
     * @param token 查询token
     * @return ServerResponse
     */
    @Override
    public ServerResponse<?> fastNormalOrderMatchPolicy(String token) {
        ServerResponse<?> serverResponse = ServerResponse.createError(ConstantExt._ERROR_MESSAGE);
        PolicyEntity policyEntity = getEntityFromToken(token);
        if (null != policyEntity){
            //调用精确匹配方法
            String matchiScheme = ConstantExt._FAST_MARK;
            return exactNormalOrderMatchPolicy(policyEntity,matchiScheme);
        }
        return serverResponse;
    }

    /**
     * 匹配政策前的数据处理->删除数据
     *
     * @param policy 匹配数据
     * @return boolean
     */
    @Override
    public boolean dealOldData(PolicyEntity policy) {
        //记录匹配数据
        exactMatchingService.insertPolicy(policy);
        TMatchingResultsDTO tMatchingResultsQuery2 = new TMatchingResultsDTO();
        tMatchingResultsQuery2.setUserInfo(policy.getCorpName());
        //tMatchingResultsQuery2.setatsandboxDBId(ConstantExt._SAND_BOX_ID);
        List<TMatchingResultsDTOResponse> data = tmatchingresultsApi.findtMatchingResultsUsingPOST(tMatchingResultsQuery2).getData();
        if (data != null && data.size() > 0) {
            ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
            try {
                data.forEach(tMatchResp -> {
                    executorService.submit(() -> {
                        List<TMatchingResultsDTODelete> dataDel = new ArrayList<>();
                        TMatchingResultsDTODelete tMatchingResultsDTO1Del = new TMatchingResultsDTODelete();
                        tMatchingResultsDTO1Del.setId(tMatchResp.getId());
                        dataDel.add(tMatchingResultsDTO1Del);
                        TMatchingResultsDeleteDataResponseObject responseObject = tmatchingresultsApi.deletetMatchingResultsUsingPOST(dataDel);
                        if (!"SUCCESS".equals(responseObject.getMessage())){
                            log.info("匹配前数据处理失败,公司名称是:【{}】,删除失败ID：【{}】",policy.getCorpName(),tMatchResp.getId());
                        }
                    });
                });
            }catch (Exception e){
                log.info("执行删除数据线程报错：【{}】",e);
            }finally {
                executorService.shutdown();
                try {
                    executorService.awaitTermination(3000, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    log.info("执行删除数据线程超时报错：【{}】",e);
                }
            }
            return true;
        }
        return false;
    }

    private PolicyEntity getEntityFromToken(String token){
        //外部接口数据请求链接
        JSONObject tokenJsonObj = policyCondCal.queryExternalInterData(ConstantExt._DYNA_TOKEN_URL);
        if(null == tokenJsonObj
                || null == tokenJsonObj.getString("data")
                || null == tokenJsonObj.getString("msg")){
            return null;
        }
        //校验是否有msg数据可以查询
        Integer checkCode = tokenJsonObj.getInteger("data");
        if (ConstantExt._ZERO.equals(checkCode)) {
            return null;
        }
        //动态TOKEN值
        String dynamicToken = tokenJsonObj.getString("msg");
        if(StringUtils.isBlank(token)){
            return null;
        }
        //当前进行快速匹配的公司名称
        String corpName = TokenCommon.getCorpNameByToken(token);
        if (StringUtils.isBlank(corpName))return null;
        String getComInfoUrl = ConstantExt._GET_RESULT_DATA_URL+"&user_token=" + dynamicToken + "&name=" + corpName;
        JSONObject jsonObjData = policyCondCal.queryExternalInterData(getComInfoUrl);
        PolicyEntity policyEntity = policyCondCal.tokenDataToPolicyBean(jsonObjData);
        if (null == policyEntity || StringUtils.isBlank(policyEntity.toString())) return null;
        policyEntity.setCorpName(corpName);
        return policyEntity;
    }

    private Callable<ServerResponse<?>> getCallable(MatchExtService matchExtService,PolicyEntity policy){
        return () -> matchExtService.isMatchSuccess(policy);
    }

}
